package com.siyoumi.app.modules.app_fks.web;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.siyoumi.app.entity.*;
import com.siyoumi.app.modules.app_fks.entity.EnumFksFileDataType;
import com.siyoumi.app.modules.app_fks.entity.FksMsgEsData;
import com.siyoumi.app.modules.app_fks.service.*;
import com.siyoumi.app.modules.app_fks.vo.*;
import com.siyoumi.app.service.FksTagUserService;
import com.siyoumi.app.sys.service.FileHandle;
import com.siyoumi.app.sys.service.file.entity.FileUploadData;
import com.siyoumi.app.sys.vo.VoUploadFile;
import com.siyoumi.component.XApp;
import com.siyoumi.component.XBean;
import com.siyoumi.component.XEnumBase;
import com.siyoumi.component.http.InputData;
import com.siyoumi.config.SysConfig;
import com.siyoumi.controller.WxAppApiController;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.mybatispuls.JoinWrapperPlus;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/wxapp/app_fks/api")
public class ApiAppFks
        extends WxAppApiController {

    /**
     * 用户信息
     */
    @GetMapping("user_info")
    public XReturn userInfo() {
        String[] select = {
                "user_id",
                "user_name",
                "user_headimg",
                "user_phone",
                "fuser_note_count",
                "fdep_name",
                "fposi_name",
                "fposi_level",
        };
        JoinWrapperPlus<FksUser> query = SvcFksUser.getBean().listUserQuery(getUid());
        query.join(FksDepartment.table(), FksDepartment.tableKey(), "fuser_department_id");
        query.join(FksPosition.table(), FksPosition.tableKey(), "fuser_position_id");
        query.select(select);
        Map<String, Object> mapUser = SvcFksUser.getApp().firstMap(query);
        if (mapUser != null) {
            String phone = (String) mapUser.get("user_phone");
            if (XStr.hasAnyText(phone)) {
                mapUser.put("user_phone", XStr.markStar(phone, 3, 4));
            }
        }

        XReturn r = XReturn.getR(0);
        r.put("user", mapUser);

        return r;
    }

    @GetMapping("tag_list")
    public XReturn tagList() {
        String[] select = {
                "user_id",
                "user_name",
                "user_headimg",
                "ftag_id",
                "ftag_name",
        };
        JoinWrapperPlus<FksTagUser> query = SvcFksTag.getBean().listUserQuery();
        query.join(FksTag.table(), FksTag.tableKey(), "ftu_tag_id");
        query.join(SysUser.table(), SysUser.tableKey(), "ftu_uid");
        query.eq("ftag_uid", getUid());
        query.select(select);
        List<Map<String, Object>> listData = FksTagUserService.getBean().getMaps(query);

        //标签
        Map<String, String> mapTag = new TreeMap<>();
        for (Map<String, Object> item : listData) {
            String ftagId = (String) item.get("ftag_id");
            String ftagName = (String) item.get("ftag_name");
            if (!mapTag.containsKey(ftagId)) {
                mapTag.put(ftagId, ftagName);
            }
        }

        List<Object> list = new ArrayList<>();
        for (Map.Entry<String, String> itemTag : mapTag.entrySet()) {
            List<Map<String, Object>> listTagData = listData.stream().filter(item -> item.get("ftag_id").equals(itemTag.getKey()))
                    .collect(Collectors.toList());

            Map<String, Object> item = new HashMap<>();
            item.put("tag_id", itemTag.getKey());
            item.put("tag_name", itemTag.getValue());
            item.put("list", listTagData);
            list.add(item);
        }
        //非正式员工
        {
            Map<String, Object> item = new HashMap<>();
            item.put("tag_id", "99");
            item.put("tag_name", "非正式员工");

            List<Map<String, Object>> listUser = SvcFksUser.getBean().listByLevel(99, new String[]{
                    "user_id",
                    "user_name",
                    "user_headimg",
            });
            item.put("list", listUser);

            getR().put("item_99", item);
        }

        getR().put("list", list);
        return getR();
    }

    /**
     * 标签详情
     */
    @GetMapping("tag_info")
    public XReturn tagInfo() {
        String tagId = getID();
        if (XStr.isNullOrEmpty(tagId)) {
            return EnumSys.MISS_VAL.getR("miss id");
        }
        FksTag entityTag = SvcFksTag.getApp().getEntity(tagId);
        if (entityTag == null) {
            return EnumSys.ERR_VAL.getR("id异常");
        }
        if (!entityTag.getFtag_uid().equals(getUid())) {
            return EnumSys.ERR_VAL.getR("标签非法");
        }

        Map<String, Object> mapTag = XBean.toMap(entityTag, new String[]{
                "ftag_id",
                "ftag_name",
        });
        List<String> uids = SvcFksTag.getBean().getTagUids(entityTag.getKey());
        mapTag.put("uids", uids);

        XReturn r = XReturn.getR(0);
        r.put("tag", mapTag);

        return getR();
    }

    /**
     * 标签保存
     */
    @PostMapping("tag_save")
    public XReturn tagSave(@Validated VaFksTag vo, BindingResult result) {
        //统一验证
        XValidator.getResult(result);
        //
        vo.setFtag_uid(getUid());

        InputData inputData = InputData.fromRequest();
        return SvcFksTag.getBean().edit(inputData, vo);
    }

    /**
     * 标签删除
     */
    @PostMapping("tag_del")
    @Transactional(rollbackFor = Exception.class)
    public XReturn tagDel(@Validated FksTagDel vo, BindingResult result) {
        //统一验证
        XValidator.getResult(result);
        //
        vo.setUid(getUid());

        return SvcFksTag.getBean().delete(vo);
    }

    /**
     * 知识库列表
     */
    @GetMapping("msg_list")
    public XReturn msgList() {
        InputData inputData = InputData.fromRequest();
        String collect = inputData.input("collect");

        JoinWrapperPlus<FksMsg> query = SvcFksMsg.getBean().listApiQuery(inputData);
        if ("1".equals(collect)) { //用户收藏列表
            String sqlExists = "SELECT 1 FROM wx_app_x.t_fks_collect WHERE fc_uid = {0} AND fmsg_id = fc_type_id AND fc_type = 0";
            query.exists(sqlExists, getUid());
        }

        IPage<FksMsg> page = new Page<>(inputData.getPageIndex(), inputData.getPageSize(), false);
        //list
        IPage<Map<String, Object>> pageData = SvcFksMsg.getApp().getMaps(page, query);
        List<Map<String, Object>> list = pageData.getRecords();
        //收藏列表
        List<String> msgIds = list.stream().map(item -> (String) item.get("fmsg_id")).collect(Collectors.toList());
        List<FksCollect> listCollect = SvcFksMsg.getBean().getListCollect(msgIds);

        for (Map<String, Object> item : list) {
            FksMsg entity = XBean.fromMap(item, FksMsg.class);

            //收藏状态
            FksCollect entityCollect = listCollect.stream().filter(i -> i.getFc_type_id().equals(entity.getFmsg_id())).findFirst().orElse(null);
            item.put("is_collect", entityCollect != null);
        }

        getR().setData("list", list);

        return getR();
    }

    /**
     * 知识库，搜索
     */
    @GetMapping("msg_search")
    public XReturn msgSearch(@Validated FksMsgEsSearchVo vo, BindingResult result) {
        //通用验证
        XValidator.getResult(result, true, true);

        InputData inputData = InputData.fromRequest();
        //赋值页码
        vo.setPage(getPageIndex());
        vo.setPageSize(getPageSize());

        IPage<FksMsgEsData> pageData = SvcFksMsgEs.getBean().searchList(vo);
        List<FksMsgEsData> list = pageData.getRecords();
        List<Map<String, Object>> listData = new ArrayList<>();
        if (list.size() > 0) {
            //获取收藏列表
            List<String> msgIds = list.stream().map(FksMsgEsData::getId).collect(Collectors.toList());
            List<FksCollect> listCollect = SvcFksMsg.getBean().getListCollect(msgIds);
            //根据搜索ID获取数据库记录
            List<Map<String, Object>> listMsg = new ArrayList<>();
            {
                JoinWrapperPlus<FksMsg> query = SvcFksMsg.getBean().listApiQuery(inputData);
                query.in("fmsg_id", msgIds);
                listMsg = SvcFksMsg.getApp().getMaps(query);
            }
            //按搜索ID进行排序
            for (FksMsgEsData item : list) {
                Map<String, Object> mapMsg = listMsg.stream().filter(i -> i.get("fmsg_id").equals(item.getId())).findFirst().orElse(null);
                FksMsg entityMsg = SvcFksMsg.getApp().loadEntity(mapMsg);

                //收藏状态
                FksCollect entityCollect = listCollect.stream().filter(i -> i.getFc_type_id().equals(entityMsg.getFmsg_id())).findFirst().orElse(null);
                mapMsg.put("is_collect", entityCollect != null);
                listData.add(mapMsg);
            }
        }

        getR().setData("total", pageData.getTotal());
        getR().setData("list", listData);
        return getR();
    }

    //知识库详情
    @GetMapping("msg_info")
    public XReturn msgInfo() {
        String msgId = input("msg_id");
        if (XStr.isNullOrEmpty(msgId)) {
            return EnumSys.MISS_VAL.getR("miss msg_id");
        }

        FksMsg entityMsg = SvcFksMsg.getApp().getEntity(msgId);
        if (entityMsg == null) {
            return EnumSys.ERR_VAL.getR("msg_id error");
        }

        Map<String, Object> mapMsg = XBean.toMap(entityMsg, new String[]{
                "fmsg_id",
                "fmsg_title",
                "fmsg_text",
                "fmsg_release_date",
                "fmsg_src",
        });
        mapMsg.put("file_json", JSON.parseArray(entityMsg.getFmsg_file_json(), Map.class)); //文件
        mapMsg.put("is_collect", SvcFksMsg.getBean().getEntityCollect(0, entityMsg.getFmsg_id(), getUid()) != null); //收藏状态
        getR().setData("msg", mapMsg);

        return getR();
    }

    //知识库收藏
    @PostMapping("msg_collect")
    public XReturn msgCollect(@Validated VoFksMsgCollect vo, BindingResult result) {
        //通用验证
        XValidator.getResult(result, true, true);
        //
        vo.setUid(getUid());

        return SvcFksMsg.getBean().collect(vo);
    }

    //城市列表
    @GetMapping("city_list")
    public XReturn cityList() {
        InputData inputData = InputData.fromRequest();

        String[] select = {
                "fcity_id",
                "fcity_name",
                "fcity_pic",
        };
        JoinWrapperPlus<FksCity> query = SvcFksCtiy.getBean().listQuery(inputData);
        query.select(select);

        IPage<FksCity> page = new Page<>(inputData.getPageIndex(), inputData.getPageSize(), false);
        //list
        IPage<Map<String, Object>> pageData = SvcFksCtiy.getApp().getMaps(page, query);
        List<Map<String, Object>> list = pageData.getRecords();

        getR().setData("list", list);

        return getR();
    }

    /**
     * 文件列表
     * 共享，核心数据
     */
    @GetMapping("file_list")
    public XReturn fileList() {
        InputData inputData = InputData.fromRequest();
        Integer type = XStr.toInt(inputData.input("type", "1"));
        String onlyUser = inputData.input("only_user");
        String typeId = inputData.input("type_id");
        if (type == 1) {
            if (XStr.isNullOrEmpty(typeId) && !"1".equals(onlyUser)) {
                return EnumSys.MISS_VAL.getR("缺少共享空间类型");
            }
        }

        String[] select = {
                "ffile_id",
                "ffile_folder",
                "ffile_type",
                "ffile_folder_id",
                "ffile_data_type",
                "ffile_uid",
                "ffile_name",
                "ffile_create_date",
                "ffile_auth",
                "ffile_path",
                "ffile_file_url",
                "ffile_file_ext",
                "ffile_file_size",
                "ffile_order",
        };
        JoinWrapperPlus<FksFile> query = SvcFksFile.getBean().listQuery(type, inputData);
        query.select(select);
        query.orderByDesc("ffile_folder")
                .orderByAsc("ffile_order")
                .orderByAsc("ffile_id");
        if ("1".equals(onlyUser)) {
            query.eq("ffile_uid", getUid());
        }

        if (XStr.hasAnyText(typeId)) { //类型ID
            switch (typeId) {
                case "common": //公司
                    break;
                case "department": //部门
                    break;
                case "person": //个人
                    query.eq("ffile_uid", getUid());
                    break;
            }
        }

        IPage<FksFile> page = new Page<>(inputData.getPageIndex(), inputData.getPageSize(), false);
        //list
        IPage<Map<String, Object>> pageData = SvcFksFile.getApp().getMaps(page, query);
        List<Map<String, Object>> list = pageData.getRecords();
        //
        EnumFksFileDataType enumDataType = XEnumBase.of(EnumFksFileDataType.class);
        //
        for (Map<String, Object> item : list) {
            FksFile entity = XBean.fromMap(item, FksFile.class);
            //数据分类
            item.put("date_type", enumDataType.get(entity.getFfile_data_type()));
            //大小
            item.put("file_size", SvcFksFile.fileSize(entity.getFfile_file_size()));

            if (entity.getFfile_auth() != 0) {
                item.put("ffile_path", null);
                item.put("ffile_file_url", null);
            }
        }

        getR().setData("list", list);

        if (type == 1) { //共享空间
            FksUser entityUser = SvcFksUser.getBean().getEntity(getUid());
            //职位等级
            getR().put("position_level", SvcFksPosition.getBean().getPositionLevel(entityUser.getFuser_position_id()));
        }

        return getR();
    }

    /**
     * 文件或文件夹，权限验证
     */
    @GetMapping("file_auth")
    public XReturn fileAuth() {
        String fileId = input("file_id");
        if (XStr.isNullOrEmpty(fileId)) {
            return EnumSys.MISS_VAL.getR("miss file_id");
        }
        FksFile entityFile = SvcFksFile.getApp().first(fileId);
        if (entityFile == null) {
            return EnumSys.ERR_VAL.getR("找不到文件");
        }
        if (entityFile.getFfile_type() != 1) {
            return EnumSys.ERR_VAL.getR("文件类型异常");
        }

        FksUser entityUser = SvcFksUser.getBean().getEntity(getUid());
        XReturn r = FksFileAuthHandle.of("look").handle(FksFileAuthHandleData.of(entityFile, entityUser));
        if (r.err()) {
            r.setErrMsg(entityFile.getFfile_name(), ": ", r.getErrMsg());
            return r;
        }

        getR().put("file", entityFile);
        return getR();
    }

    /**
     * 文件删除
     */
    @PostMapping("file_del")
    public XReturn fileDel(@Validated FksFileDel vo, BindingResult result) {
        //通用验证
        XValidator.getResult(result, true, true);
        return SvcFksFile.getBean().fileDel(vo);
    }

    @PostMapping("file_move")
    public XReturn fileMove(@Validated FksFileMove vo, BindingResult result) {
        //通用验证
        XValidator.getResult(result, true, true);
        //
        return SvcFksFile.getBean().fileMove(vo);
    }

    /**
     * 文件添加
     */
    //@PostMapping("file_add")
    //public XReturn fileAdd(@Validated FksFileAdd vo, BindingResult result) {
    //    //统一验证
    //    XValidator.getResult(result, true);
    //    return SvcFksFile.getBean().fileAdd(vo);
    //}

    /**
     * 文件批量添加
     *
     * @param vo
     * @param result
     */
    @PostMapping("file_add_batch")
    public XReturn fileAddBatch(@Validated @RequestBody FksFileAddBatch vo, BindingResult result) {
        //统一验证
        XValidator.getResult(result, true);
        //
        return SvcFksFile.getBean().fileAdd(vo);
    }

    //文件上传
    @PostMapping({"/file_upload"})
    public XReturn uploadFile(@Validated VoUploadFile vo, BindingResult result) {
        //统一验证
        XValidator.getResult(result, true, true);

        vo.setType("aliyun");

        List<String> ex = SvcFksFile.fileAccept().stream().map(item -> item.substring(1, item.length())).collect(Collectors.toList());

        String saveFileDir = XStr.format("app/data_1_0");
        FileUploadData data = FileUploadData.of(vo.getFile0(), ex, SysConfig.getIns().getUploadFileSizeMax(), saveFileDir);
        return FileHandle.of(vo.getType()).uploadFile(data);
    }
}
